package com.unlcn.ils.sales.api.rest;

import cn.huiyunche.commons.domain.PageVo;
import cn.huiyunche.commons.domain.ResultDTO;
import cn.huiyunche.commons.exception.BusinessException;
import com.google.common.collect.Lists;
import com.unlcn.ils.sales.api.dto.*;
import com.unlcn.ils.sales.api.query.OrderQuery;
import com.unlcn.ils.sales.backend.bo.*;
import com.unlcn.ils.sales.backend.enums.OrderAuditStatusEnum;
import com.unlcn.ils.sales.backend.enums.OrderStatusEnum;
import com.unlcn.ils.sales.backend.service.OrderService;
import com.unlcn.ils.sales.backend.util.DateUtils;
import io.swagger.annotations.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Created by houjianhui on 2017/6/2.
 */
@Controller
@RequestMapping(value = "/api/order", produces = MediaType.APPLICATION_JSON_VALUE)
@Api(value = "/order", description = "销售订单")
public class OrderRest {
    private static final Logger LOGGER = LoggerFactory.getLogger(OrderRest.class);

    @Autowired
    private OrderService orderService;

    /**
     * 保存销售订单
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @ApiOperation(value = "保存销售订单", notes = "保存销售订单", produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public ResultDTO<Object> save(OrderSaveDTO dto, @Valid BindingResult br) {
        ResultDTO<Object> result = new ResultDTO<>(true, null, "下单成功");
        OrderBO orderBO = new OrderBO();
        BeanUtils.copyProperties(dto, orderBO);
        orderBO.setPickDate(DateUtils.StrToDate(dto.getPickDate(), "yyyy-MM-dd"));
        try {
            result.setData(orderService.save(orderBO, br));
        } catch (Exception e) {
            LOGGER.error("OrderRest save error: {}", e);
            throw new BusinessException(e.getMessage());
        }
        return result;
    }

    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ApiOperation(value = "查询销售订单", notes = "查询销售订单", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiResponses(value = {@ApiResponse(code = 404, message = "list not found")})
    @ResponseBody
    public ResultDTO<Object> listSaleOrder(PageVo pageVo, OrderQuery query) {
        ResultDTO<Object> result = new ResultDTO<>(true, null, "查询销售订单成功");
        OrderQueryBO bo = new OrderQueryBO();
        BeanUtils.copyProperties(query, bo);
        try {
            Map<String, Object> map = orderService.listSaleOrder(pageVo, bo);
            List<OrderDTO> orderDTOS = Lists.newArrayList();
            if (!Objects.equals(map, null) && map.size() > 0) {
                List<OrderViewBO> orders = (ArrayList) map.get("orderList");
                if (CollectionUtils.isNotEmpty(orders)) {
                    orders.stream().forEach(val -> {
                        OrderDTO order = new OrderDTO();
                        BeanUtils.copyProperties(val, order);
                        String brand = val.getBrands() + "个品牌，" + val.getSeriesAmt() + "台车";
                        if (Objects.equals(order.getOrderStatus(), OrderStatusEnum.ORDER_INIT.getValue())) {
                            order.setOrderStatusText(OrderAuditStatusEnum.getByValue(order.getAuditStatus()).getText());
                        } else {
                            order.setOrderStatusText(OrderStatusEnum.getByValue(order.getOrderStatus()).getText());
                        }
                        order.setBrandSeries(brand);
                        orderDTOS.add(order);
                    });
                }
            }
            map.put("orderList", orderDTOS);
            result.setData(map);
        } catch (Exception e) {
            LOGGER.error("OrderRest list error: {}", e);
            throw new BusinessException(e.getMessage());
        }
        return result;
    }

    @RequestMapping(value = "/detail/{orderId}", method = RequestMethod.GET)
    @ApiOperation(value = "查询销售订单明细", notes = "查询销售订单明细", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiResponses(value = {@ApiResponse(code = 404, message = "detail not found")})
    @ResponseBody
    public ResultDTO<Object> getSaleOrderDetail(@ApiParam(value = "销售订单ID ", required = true) @PathVariable(value = "orderId") Integer orderId) {
        ResultDTO<Object> result = new ResultDTO<>(true, null, "查询销售订单明细成功");
        try {
            OrderDetailDTO detailDTO = new OrderDetailDTO();
            OrderViewBO viewBO = orderService.getSaleOrderByOrderId(orderId);
            BeanUtils.copyProperties(viewBO, detailDTO);
            if (!Objects.equals(viewBO, null) || !Objects.equals(viewBO, "")) {
                List<OrderSkuBO> skuBOS = viewBO.getOrderSkus();
                List<OrderSkuDTO> skuDTOS = Lists.newArrayList();
                if (CollectionUtils.isNotEmpty(skuBOS)) {
                    skuBOS.stream().forEach(val -> {
                        OrderSkuDTO skuDTO = new OrderSkuDTO();
                        BeanUtils.copyProperties(val, skuDTO);
                        skuDTOS.add(skuDTO);
                    });
                }

                List<OrderAttachViewBO> attachs = viewBO.getAttachs();
                List<OrderAttachDTO> attachDTOS = Lists.newArrayList();
                if (CollectionUtils.isNotEmpty(attachs)) {
                    attachs.stream().forEach(val -> {
                        OrderAttachDTO attachDTO = new OrderAttachDTO();
                        BeanUtils.copyProperties(val, attachDTO);
                        attachDTOS.add(attachDTO);
                    });
                }
                detailDTO.setAttachs(attachDTOS);
                detailDTO.setOrderSkus(skuDTOS);
            }
            result.setData(detailDTO);
        } catch (Exception e) {
            LOGGER.error("OrderRest getSaleOrderDetail error: {}", e);
            throw new BusinessException(e.getMessage());
        }
        return result;
    }

    /**
     * 查询销售订单价格
     *
     * @param departId 起运地ID
     * @param destId   目的地ID
     * @param amt      车型数量
     * @return
     */
    @RequestMapping(value = "/price/{departId}/{destId}/{amt}", method = RequestMethod.GET)
    @ApiOperation(value = "查询销售订单价格", notes = "查询销售订单价格", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiResponses(value = {@ApiResponse(code = 404, message = "getOrderPrice not found")})
    @ResponseBody
    public ResultDTO<Object> getOrderPrice(@ApiParam(value = "起运地ID", required = true) @PathVariable(value = "departId") Integer departId,
                                           @ApiParam(value = "目的地ID", required = true) @PathVariable(value = "destId") Integer destId,
                                           @ApiParam(value = "商品车数量", required = true) @PathVariable(value = "amt") Integer amt) {
        ResultDTO<Object> result = new ResultDTO<>(true, null, "查询销售订单价格成功");
        try {
            result.setData(orderService.getOrderPrice(departId, destId, amt));
        } catch (Exception e) {
            LOGGER.error("OrderRest getOrderPrice error: {}", e);
            throw new BusinessException(e.getMessage());
        }
        return result;
    }

    /**
     * 运价查询
     *
     * @param departId 起运地ID
     * @param destId   目的地ID
     * @return
     */
    @RequestMapping(value = "/price/{departId}/{destId}", method = RequestMethod.GET)
    @ApiOperation(value = "运价查询", notes = "运价查询", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiResponses(value = {@ApiResponse(code = 404, message = "getOrderPrice not found")})
    @ResponseBody
    public ResultDTO<Object> getOrderPrice(@ApiParam(value = "起运地ID", required = true) @PathVariable(value = "departId") Integer departId,
                                           @ApiParam(value = "目的地ID", required = true) @PathVariable(value = "destId") Integer destId) {
        ResultDTO<Object> result = new ResultDTO<>(true, null, "销售订单运价查询成功");
        try {
            result.setData(orderService.getOrderPrice(departId, destId));
        } catch (Exception e) {
            LOGGER.error("OrderRest getOrderPrice error: {}", e);
            throw new BusinessException(e.getMessage());
        }
        return result;
    }

    /**
     * 更新销售订单状态
     *
     * @param orderCode   销售订单编码
     * @param orderStatus 销售订单状态
     * @return
     */
    @RequestMapping(value = "/updateStatus/{orderCode}/{orderStatus}", method = RequestMethod.POST)
    @ApiOperation(value = "更新销售订单状态", notes = "更新销售订单状态", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiResponses(value = {@ApiResponse(code = 404, message = "updateOrderStatusByOrderCode not found")})
    @ResponseBody
    public ResultDTO<Object> updateOrderStatusByOrderCode(@ApiParam(value = "销售订单编号", required = true) @PathVariable(value = "orderCode") String orderCode,
                                                          @ApiParam(value = "销售订单状态", required = true) @PathVariable(value = "orderStatus") String orderStatus) {
        ResultDTO<Object> result = new ResultDTO<>(true, null, "销售订单状态更新成功");
        try {
            result.setData(orderService.updateOrderStatusByOrderCode(orderCode, Objects.equals(orderStatus, null) ? null : Integer.valueOf(orderStatus)));
        } catch (Exception e) {
            LOGGER.error("OrderRest getOrderPrice error: {}", e);
            throw new BusinessException(e.getMessage());
        }
        return result;
    }

    /**
     * 销售订单是否有提成
     *
     * @param standardSalePrice   销售订单标准价格
     * @param suggestSalePrice 销售人员建议价格
     * @return
     */
    @RequestMapping(value = "/iscarry", method = RequestMethod.POST)
    @ApiOperation(value = "销售订单是否有提成", notes = "销售订单是否有提成", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiResponses(value = {@ApiResponse(code = 404, message = "updateOrderStatusByOrderCode not found")})
    @ResponseBody
    public ResultDTO<Object> isCarry(@ApiParam(value = "销售订单标准价格", required = true) String standardSalePrice,
                                     @ApiParam(value = "销售人员建议价格", required = true) String suggestSalePrice) {
        ResultDTO<Object> result = new ResultDTO<>(true, null, "销售订单状态更新成功");
        if (StringUtils.isBlank(standardSalePrice)) {
            LOGGER.info("OrderRest.isCarry standardSalePrice must not be null");
            throw new BusinessException("销售订单标准价格不能为空");
        } else if (StringUtils.isBlank(suggestSalePrice)) {
            LOGGER.info("OrderRest.isCarry suggestSalePrice must not be null");
            throw new BusinessException("销售人员建议价格不能为空");
        }
        try {
            BigDecimal standardPrice = BigDecimal.valueOf(Double.valueOf(standardSalePrice)).multiply(BigDecimal.valueOf(0.9)).setScale(2, BigDecimal.ROUND_HALF_UP);
            Boolean bool = true;
            if (standardPrice.compareTo(BigDecimal.valueOf(Double.valueOf(suggestSalePrice))) == -1) {
                bool = false;
            }
            result.setData(bool);
        } catch (Exception e) {
            LOGGER.error("OrderRest getOrderPrice error: {}", e);
            throw new BusinessException(e.getMessage());
        }
        return result;
    }


    /**
     * 销售订单附件审核
     *
     * @param orderCode   销售订单编码
     * @param attachAuditStatus 销售订单附件审核状态
     * @return
     */
    @RequestMapping(value = "/updateAttachAuditStatus", method = RequestMethod.POST)
    @ApiOperation(value = "销售订单附件审核", notes = "销售订单附件审核", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiResponses(value = {@ApiResponse(code = 404, message = "updateAttachAuditStatusByOrderCode not found")})
    @ResponseBody
    public ResultDTO<Object> updateAttachAuditStatusBySaleOrderCode(@ApiParam(value = "销售订单编码", required = true) String orderCode,
                                     @ApiParam(value = "销售订单附件审核状态", required = true) Integer attachAuditStatus ) {
        ResultDTO<Object> result = new ResultDTO<>(true, null, "销售订单审核状态更新成功");
        if (StringUtils.isBlank(orderCode)) {
            LOGGER.info("OrderRest.updateAttachAuditStatusBySaleOrderCode orderCode must not be null");
            throw new BusinessException("销售订单编码");
        } else if (Objects.equals(attachAuditStatus, null)) {
            LOGGER.info("OrderRest.updateAttachAuditStatusBySaleOrderCode attachAuditStatus must not be null");
            throw new BusinessException("销售订单附件审核状态");
        }
        try {
            result.setData(orderService.updateAttachAuditStatusBySaleOrderCode(orderCode, attachAuditStatus));
        } catch (Exception e) {
            LOGGER.error("OrderRest updateAttachAuditStatusBySaleOrderCode error: {}", e);
            throw new BusinessException(e.getMessage());
        }
        return result;
    }

}
